package pl.edu.pk.mech.kkbus.controller;

import java.util.List;
import java.util.Set;
import java.util.logging.Logger;

import javax.validation.ConstraintViolation;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import pl.edu.pk.mech.kkbus.component.MyValidator;
import pl.edu.pk.mech.kkbus.model.ResponseStatus;
import pl.edu.pk.mech.kkbus.model.User;
import pl.edu.pk.mech.kkbus.service.UserService;

@Controller
public class UserController extends RestController {
    
    private static final Logger log = Logger.getLogger(UserController.class.getName());
    
    @Autowired
    UserService userService;
    
    @Autowired
    MyValidator validatorComponent;
    
    @RequestMapping(value = "/users", method = RequestMethod.GET)
    public @ResponseBody List<User> getUsers(@RequestParam(required = false, defaultValue = "-1") int page) {
        if (page < 0) {
            log.info("Get all users");
            return userService.getUsers();
        } else {        
            log.info("Get part users. Page: " + page);
            return null;
        }         
    } 
    
    @RequestMapping(value = "/user/ban/{id}", method = RequestMethod.PUT) 
   public @ResponseBody ResponseStatus banUser(@PathVariable long id) { 
       boolean result = userService.banUser(id, false); 
       return result ? ResponseStatus.UPDATED : ResponseStatus.ERROR; 
   }
    
    
      @RequestMapping(value = "/user/unban/{id}", method = RequestMethod.PUT) 
   public @ResponseBody ResponseStatus unbanUser(@PathVariable long id) { 
       boolean result = userService.banUser(id, true); 
       return result ? ResponseStatus.UPDATED : ResponseStatus.ERROR; 
   }
    
    
    @RequestMapping(value = "/users/{role}", method = RequestMethod.GET)
    public @ResponseBody List<User> getUsersByRole(@PathVariable String role) {
        return userService.loadUserByRole(role);
    } 
    
    @RequestMapping(value = "/user", method = RequestMethod.POST)
    public @ResponseBody ResponseStatus createUser(@RequestBody User user) {   
        boolean validation = true;
        
        log.info("=== VALIDATION ===");
        Set<ConstraintViolation<User>> violations = validatorComponent.
                getValidatorInstance().validate(user);
        for (ConstraintViolation<User> violation : violations) {
            validation = false;
            
            String propertyPath = violation.getPropertyPath().toString();
            String message = violation.getMessage();
            
            log.info(propertyPath + " " + message);
        }
        
        if (validation) {
            boolean result = userService.createUser(user);
            
            return result ? ResponseStatus.ADDED : ResponseStatus.ERROR;
        } else {
            return ResponseStatus.ERROR;
        }
    }
    
    @RequestMapping(value = "/user/{id}", method = RequestMethod.PUT)
    public @ResponseBody ResponseStatus editUser(@PathVariable String id, @RequestBody User user) {
        boolean result = userService.updateUser(user);
        return result ? ResponseStatus.UPDATED : ResponseStatus.ERROR;
    }
    
    @RequestMapping(value = "/user/{id}", method = RequestMethod.GET)
    public @ResponseBody User getUser(@PathVariable long id) {        
        return userService.getUser(id);
    }  
    
    @RequestMapping(value = "/user/{id}", method = RequestMethod.DELETE)
    public @ResponseBody ResponseStatus deleteUser(@PathVariable long id) {
        userService.deleteUser(id);        
        return ResponseStatus.DELETED;
    }
    
    @RequestMapping(value = "/user/authenticated", method = RequestMethod.GET)
    public @ResponseBody User getUser() {
        String principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal().toString();
        
        User user = userService.loadUserByEmail(principal);
        user.setPassword("");
        
        return user;
    } 
    
    @RequestMapping(value = "/user/activate/{hash}", method = RequestMethod.GET)
    public @ResponseBody ResponseStatus activateUser(@PathVariable String hash) {
        log.info("Activate user with hash: " + hash);
        
        boolean result = userService.activateUser(hash);
    
        return (result == true) ? ResponseStatus.SUCCESS : ResponseStatus.ERROR;
    }
}
